#include <xeno/config.h>
+#include <hypervisor-ifs/hypervisor-if.h>
#include <asm/page.h>
#define SECONDARY_CPU_FLAG 0xA5A5A5A5
.word 0
gdt_descr:
- .word (2*NR_CPUS+8)*8-1
+ .word (LAST_RESERVED_GDT_ENTRY*8)+7
SYMBOL_NAME(gdt):
.long SYMBOL_NAME(gdt_table) /* gdt base */
.word 0
nopaging_gdt_descr:
- .word (2*NR_CPUS+8)*8-1
+ .word (LAST_RESERVED_GDT_ENTRY*8)+7
.long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
ALIGN
/* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */
/* machine->physical mapping table. Ring 0 can access all memory. */
ENTRY(gdt_table)
- .quad 0x0000000000000000 /* 0x0000 NULL descriptor */
- .quad 0x00cf9a000000ffff /* 0x0008 ring 0 4.00GB code at 0x0 */
- .quad 0x00cf92000000ffff /* 0x0010 ring 0 4.00GB data at 0x0 */
- .quad 0x00cfba000000c3ff /* 0x0019 ring 1 3.95GB code at 0x0 */
- .quad 0x00cfb2000000c3ff /* 0x0021 ring 1 3.95GB data at 0x0 */
- .quad 0x00cffa000000c3ff /* 0x002b ring 3 3.95GB code at 0x0 */
- .quad 0x00cff2000000c3ff /* 0x0033 ring 3 3.95GB data at 0x0 */
+ .fill FIRST_RESERVED_GDT_ENTRY,8,0
+ .quad 0x0000000000000000 /* unused */
+ .quad 0x00cf9a000000ffff /* 0x0808 ring 0 4.00GB code at 0x0 */
+ .quad 0x00cf92000000ffff /* 0x0810 ring 0 4.00GB data at 0x0 */
+ .quad 0x00cfba000000c3ff /* 0x0819 ring 1 3.95GB code at 0x0 */
+ .quad 0x00cfb2000000c3ff /* 0x0821 ring 1 3.95GB data at 0x0 */
+ .quad 0x00cffa000000c3ff /* 0x082b ring 3 3.95GB code at 0x0 */
+ .quad 0x00cff2000000c3ff /* 0x0833 ring 3 3.95GB data at 0x0 */
.quad 0x0000000000000000 /* unused */
.fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
long ret = -EINVAL;
struct pfn_info *page;
- if ( (entries < FIRST_DOMAIN_GDT_ENTRY) || (entries > 8192) )
+ if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) )
return -EINVAL;
if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
local_flush_tlb();
- /* Copy over first entries of the new GDT. */
- memcpy((void *)GDT_VIRT_START, gdt_table, FIRST_DOMAIN_GDT_ENTRY*8);
+ /* Copy reserved GDT entries to the new GDT. */
+ memcpy((struct desc_struct *)GDT_VIRT_START + FIRST_RESERVED_GDT_ENTRY,
+ gdt_table + FIRST_RESERVED_GDT_ENTRY,
+ NR_RESERVED_GDT_ENTRIES*8);
SET_GDT_ADDRESS(current, GDT_VIRT_START);
SET_GDT_ENTRIES(current, (entries*8)-1);
switch ( (page->flags & PG_type_mask) )
{
case PGT_gdt_page:
- /* Disallow updates of Xen-private descriptors in the current GDT. */
+ /* Disallow updates of Xen-reserved descriptors in the current GDT. */
if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) &&
- (((pa&(PAGE_SIZE-1))>>3) < FIRST_DOMAIN_GDT_ENTRY) )
+ (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
+ (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
goto out;
case PGT_ldt_page:
case PGT_writeable_page:
*/
#include <xeno/config.h>
+#include <hypervisor-ifs/hypervisor-if.h>
#include <asm/page.h>
#ifdef CONFIG_SMP
.word 0, 0 # idt base = 0L
gdt_48:
- .word 0x0800 # gdt limit = 2048, 256 GDT entries
- .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU)
+ .word (LAST_RESERVED_GDT_ENTRY*8)+7
+ .long gdt_table-__PAGE_OFFSET
.globl SYMBOL_NAME(trampoline_end)
SYMBOL_NAME_LABEL(trampoline_end)
#define LDT_ENTRY_SIZE 8
-#define __FIRST_TSS_ENTRY 8
-#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1)
+#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8)
+#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1)
#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY)
#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY)
/*
* Guest OS must provide its own code selectors, or use the one we provide.
* The RPL must be 1, as we only create bounce frames to ring 1.
+ * Any LDT selector value is okay.
*/
-#define VALID_CODESEL(_s) \
- (((((_s)>>2) >= FIRST_DOMAIN_GDT_ENTRY) || ((_s) == FLAT_RING1_CS)) && \
- (((_s)&3) == 1))
-#define VALID_DATASEL(_s) \
- (((((_s)>>2) >= FIRST_DOMAIN_GDT_ENTRY) || ((_s) == FLAT_RING1_DS)) && \
+#define VALID_SEL(_s) \
+ (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || \
+ (((_s)>>3) > LAST_RESERVED_GDT_ENTRY) || \
+ ((_s)&4)) && \
(((_s)&3) == 1))
+#define VALID_CODESEL(_s) ((_s) == FLAT_RING1_CS || VALID_SEL(_s))
+
+#define VALID_DATASEL(_s) ((_s) == FLAT_RING1_DS || VALID_SEL(_s))
+
/* These are bitmasks for the first 32 bits of a descriptor table entry. */
#define _SEGMENT_TYPE (15<< 8)
#define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */
/*
* SEGMENT DESCRIPTOR TABLES
*/
-/* The first few GDT entries are reserved by Xen. */
-#define FIRST_DOMAIN_GDT_ENTRY 40
/*
- * These flat segments are in the Xen-private section of every GDT. Since
- * these are also present in the initial GDT, many OSes will be able to avoid
+ * A number of GDT entries are reserved by Xen. These are not situated at the
+ * start of the GDT because some stupid OSes export hard-coded selector values
+ * in their ABI. These hard-coded values are always near the start of the GDT,
+ * so Xen places itself out of the way.
+ *
+ * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
+ * and LAST_RESERVED_GDT_ENTRY are reserved).
+ */
+#define NR_RESERVED_GDT_ENTRIES 40
+#define FIRST_RESERVED_GDT_ENTRY 256
+#define LAST_RESERVED_GDT_ENTRY \
+ (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
+
+/*
+ * These flat segments are in the Xen-private section of every GDT. Since these
+ * are also present in the initial GDT, many OSes will be able to avoid
* installing their own GDT.
*/
-#define FLAT_RING1_CS 0x0019
-#define FLAT_RING1_DS 0x0021
-#define FLAT_RING3_CS 0x002b
-#define FLAT_RING3_DS 0x0033
+#define FLAT_RING1_CS 0x0819
+#define FLAT_RING1_DS 0x0821
+#define FLAT_RING3_CS 0x082b
+#define FLAT_RING3_DS 0x0833
/*
#define barrier() __asm__ __volatile__("": : :"memory")
-#define __HYPERVISOR_CS 0x0008
-#define __HYPERVISOR_DS 0x0010
+#define __HYPERVISOR_CS 0x0808
+#define __HYPERVISOR_DS 0x0810
#define NR_syscalls 256
/* Part of the domain API. */
int do_process_page_updates(page_update_request_t *updates, int count);
-#define DEFAULT_GDT_ENTRIES ((FIRST_DOMAIN_GDT_ENTRY*8)-1)
+#define DEFAULT_GDT_ENTRIES ((LAST_RESERVED_GDT_ENTRY*8)+7)
#define DEFAULT_GDT_ADDRESS ((unsigned long)gdt_table)
#endif /* __XENO_MM_H__ */